﻿#if NETFX
using System.Windows.Media;
using System.Windows.Data;
#elif NETFX_CORE
using Windows.UI;
using Windows.UI.Xaml.Data;

#endif

using GalaSoft.MvvmLight;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Collections.ObjectModel;
using GalaSoft.MvvmLight.Messaging;


using NicoView.Model.Service;
using NicoView.Model.Service.Events;
using NicoView.Model.Service.Lives;
using System.Windows;

using System.ComponentModel;
using System.Diagnostics;
using NicoView.Model.Service.Comments;
using NicoView.Model;
using NicoView.ViewModel.Message;

namespace NicoView.ViewModel
{

    

    public abstract class NicoViewCommentListViewModelBase:NicoViewViewModelBase,IDisposable
    {
        protected internal NicoViewCommentCollection comments;



        internal NicoViewCommentListViewModelBase()
        {
            comments = new NicoViewCommentCollection();
            this.commentClient = null;

            AutoScroll = false;

            




        }

        ~NicoViewCommentListViewModelBase()
        {

        }

        public new void Dispose()
        {

            ClearComments();

            base.Dispose();
            
        }


        public void ClearComments()
        {
            foreach (var comment in this.Comments)
            {
                comment.Dispose();
            }
            Comments.Clear();
        }

        public void Set(INicoCommentClient commentClient)
        {
            this.CommentClient = commentClient;
            this.ClearComments();
            this.Comments.Upgrade();
            AutoScroll = true;


        }

        public abstract void Loded();


        public virtual bool IsCommentAccepted(NicoViewCommentViewModel comment)
        {
            return comment.VisibleComment &&
                    (!comment.CommentScoreRank.IsNotShowNgRank(this.InternalApplication.Instance.Property.CommentNgShareLevel));
        }

        

        


        public virtual bool AutoScroll { get;  set; }





        protected internal INicoCommentClient commentClient;

        public INicoCommentClient CommentClient
        {
            get
            {
                return this.commentClient;
            }
            set
            {
                if (this.commentClient != null)
                {
                    this.commentClient.Received -= _onAddComment;
                    this.commentClient.ReceivePeriod -= _onPeriod;
                }

                this.commentClient = value;

                this.commentClient.Received += _onAddComment;

                this.commentClient.ReceivePeriod += _onPeriod;

            }
        }

        private void _onPeriod(NicoCommentReceivePeriodEventArgs args)
        {
            
            onPeriod(args);

            

        }

        protected internal abstract void onAddComment(NicoCommentReceiveEventArgs args);

        protected internal abstract void onPeriod(NicoCommentReceivePeriodEventArgs args);

        public abstract void ConnectLive();

        private void _onAddComment(NicoCommentReceiveEventArgs args)
        {
            foreach (var comment in args.Comments)
            {
                if (comment.Date <= this.CommentClient.Info.ThreadConnectionStartTime)
                {
                    AutoScroll = true;
                    break;
                }
            }
            
            onAddComment(args);
            Add(args.Comments);
        }

      

        public NicoViewCommentCollection Comments 
        { 
            get 
            { 
                return comments; 
            }

            internal protected set
            {
                Set(()=>Comments,ref comments, value);
            }
        
        }


   



        public void Add(ICollection<NotifyNicoComment> comments)
        {
            foreach (var comment in comments)
            {
                var addcomment = new NicoViewCommentViewModel(comment, this);
                Comments.Add(addcomment);
            }


        }

        internal virtual void ShowSingleUser(NicoViewShowSingleUserInfoMessage e)
        {
            var query = from eComment in Comments
                        where eComment.Comment.User == e.User
                        select eComment.Comment;

            this.MessengerInstance.Send(new NicoViewShowUserInfoCommentsMessage(e.User, Comments,e.ApplicationDispatcher));
        }

        internal virtual void SingleNoAnchor(NicoCommentSingleNoAnchorMessage e)
        {
            var query = from comment in Comments
                        where comment.Comment.No == e.No
                        select comment;
            if (query.Count() <= 0) return;
            this.MessengerInstance.Send(new NicoViewCommentShowCommentMessage(query, e.ApplicationDispatcher));
        }

        internal virtual void MultiNoAnchor(NicoCommentMultiNoAnchorMessage e)
        {
            var query = from comment in Comments
                        where comment.Comment.No >= e.StartNo && comment.Comment.No <= e.EndNo
                        select comment;
            if (query.Count() <= 0) return;
            this.MessengerInstance.Send(new NicoViewCommentShowCommentMessage(new List<NicoViewCommentViewModel>(query),e.ApplicationDispatcher));
        }

        internal void ReplyRequest(NicoCommentReplyRequestMessage e)
        {
            this.MessengerInstance.Send(e);
        }

        internal void UrlShow(NicoCommentUrlShowMessage e)
        {
            NicoViewApplication.Current.ExecuteUrl(e.Url);
        }

        internal async void VideoShow(NicoCommentVideoShowMessage e)
        {
            var rslt = await InternalApplication.Instance.VideoConsolRequestAsync(e.VideoId, (ex) =>
            {
                this.MessengerInstance.Send(ex);


            });

            if (rslt.Value)
            {
                this.MessengerInstance.Send(new NicoViewResultShowMessage(rslt.Message));
            }
        }

        internal void ChannelShow(NicoCommentChannelShowMessage e)
        {
            this.MessengerInstance.Send(e);
        }

        internal  void LiveShow(NicoCommentLiveShowMessage e)
        {
            NicoViewApplication.Current.ExecuteLiveUrl(e.LiveId);
        }

        internal void CommunityShow(NicoCommentCommunityShowMessage e)
        {
            NicoViewApplication.Current.ExecuteCommunityUrl(e.CommunityId);
        }

        
    }
}
